package controller

import (
	"encoding/json"
	"log"
	"net/http"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/jacklin/analyze-voice/v2/server/model"
	"github.com/jacklin/analyze-voice/v2/util"
)

type FFmpeg struct {
	Sn           string `json:"sn" form:"sn" binding:"required"`
	CollectTime  string `json:"collect_time" form:"collect_time" binding:"required"`
	ModelType    string `json:"model_type" form:"model_type" binding:"required"`
	CallbackURL  string `json:"callback_url" form:"callback_url" binding:"required"`
	VoiceFileURL string `json:"voice_file_url" form:"voice_file_url" binding:"required"`
}
type Task struct {
	TaskID    string `json:"task_id"`
	Status    string `json:"status"`
	Timestamp string `json:"timestamp"`
	FFmpeg    FFmpeg `json:"ffmpeg"`
}
type Response struct {
	Status string      `json:"status"`
	Data   interface{} `json:"json"`
	Msg    string      `json:"msg"`
}

func (t *Task) SetTimestamp() {
	t.Timestamp = time.Now().Format("2006-01-02 15:04:05")
}
func (t *Task) SetStatus(status string) {
	t.Status = status
}
func (t *Task) SetTaskID() {
	t.TaskID = util.GetTaskID()
}

// 初始化Task实例对象
func (t *Task) Init(c *gin.Context) (err error) {
	t.SetTimestamp()
	t.SetStatus("pending")
	t.SetTaskID()

	// 修改: 支持 x-www-form-urlencoded 和 JSON 请求
	if c.ContentType() == "application/x-www-form-urlencoded" {
		if err := c.ShouldBind(&t.FFmpeg); err != nil {
			log.Printf("绑定请求数据失败: %v\n", err)
			c.JSON(http.StatusBadRequest, gin.H{"code": 400, "msg": "请求数据格式错误"})
			return err
		}
	} else {
		if err := c.ShouldBindJSON(&t.FFmpeg); err != nil {
			log.Printf("绑定请求数据失败: %v\n", err)
			c.JSON(http.StatusBadRequest, gin.H{"code": 400, "msg": "请求数据格式错误"})
			return err
		}
	}

	// 请求数据绑定成功后，异步处理
	go t.HandleFFMPEGProcess()
	return nil
}

func RunTask(c *gin.Context) {
	task := Task{}
	if err := task.Init(c); err != nil {
		return
	}
	// 返回 JSON 统一数据结构 状态码、响应体、错误信息
	c.JSON(http.StatusOK, gin.H{"code": 200, "data": task, "msg": "success"})

}

// 处理请求,这个需要处理大约30秒
func (t *Task) HandleFFMPEGProcess() {
	time.Sleep(3 * time.Second)
	log.Printf("HandleFFMPEGProcess... TaskID: %s, URL: %s", t.TaskID, t.FFmpeg.VoiceFileURL)

	// 使用t.FFmpeg.VoiceFileURL 下载对应的文件到/tmp/目录下
	filepath, err := util.DownloadFile(t.FFmpeg.VoiceFileURL)
	if err != nil {
		log.Printf("下载文件失败: %v\n", err)
		return
	}

	log.Printf("文件下载成功: %s", filepath)

	pcm := &model.AudioStat{}
	var audioStat []model.AudioStat
	if audioStat, err = pcm.AnalyzePCM(filepath); err != nil {
		log.Printf("分析出错: %v\n", err)
		return
	}
	log.Printf("分析完成: %v\n", audioStat)
	// 封装负载的数据
	payload := model.MQTTPayload{
		SN:           t.FFmpeg.Sn,
		CollectTime:  t.FFmpeg.CollectTime,
		TaskID:       t.TaskID,
		SegmentStats: audioStat,
	}
	// 将封装的数据转换为JSON
	mqttData, err := json.Marshal(payload)
	if err != nil {
		log.Printf("MQTT数据封装失败: %v\n", err)
		return
	}

	// 对封装的数据通过mqtt协议上报到MQTT服务端：192.168.0.80:1883
	// topic: d/EN201-LK/json/v1/E200302
	// qos: 0
	// retain: false
	log.Printf("MQTT上报: %v\n", string(mqttData))
	err = publishToMQTT(t.FFmpeg.ModelType, t.FFmpeg.Sn, string(mqttData))
	if err != nil {
		log.Printf("MQTT上报失败: %v\n", err)
	} else {
		log.Printf("MQTT上报成功，SN: %s\n", t.FFmpeg.Sn)
	}
}
